package com.pureut.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.StringUtils;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.domain.MaterialAwmateria;
import com.pureut.system.domain.MaterialCoding;
import com.pureut.system.domain.SysTheAlarm;
import com.pureut.system.domain.dto.MaterialAwmateriaDto;
import com.pureut.system.domain.dto.MaterialMqDto;
import com.pureut.system.domain.dto.ProjectRecursionDto;
import com.pureut.system.domain.vo.MaterialAlarmVo;
import com.pureut.system.domain.vo.MaterialAwmateriaVo;
import com.pureut.system.export.MaterialAwmateriaExport;
import com.pureut.system.mapper.*;
import com.pureut.system.service.IMaterialAwmateriaService;
import com.pureut.system.util.MaterialMqUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 原料信息实现类
 * @Param
 * @Date 22-11-24
 * @Author hl
 **/
@Service
public class MaterialAwmateriaServiceImpl implements IMaterialAwmateriaService {

    @Resource
    private MaterialAwmateriaMapper materialAwmateriaMapper;

    @Resource
    private SysTheAlarmMapper sysTheAlarmMapper;

    @Resource
    private MaterialCodingMapper materialCodingMapper;

    @Resource
    private SysMidSplitServiceImpl sysMidSplitServiceImpl;

    @Resource
    SysUserRoleMapper sysUserRoleMapper;

    /**
     * BomMapper
     */
    @Resource
    MaterialBomHalfMapper materialBomHalfMapper;

    /**
     * 查询原料信息
     *
     * @param materialAwmateria 原料信息
     * @return 原料信息集合
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<MaterialAwmateriaDto> selectAwmateriaList(MaterialAwmateriaVo materialAwmateria) {
        List<SysDictData> netArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<MaterialAwmateriaDto> list = materialAwmateriaMapper.selectAwmateriaList(materialAwmateria);
        for (MaterialAwmateriaDto dto :
                list) {
            dto.setMaterialUnitDict(netMap.get(String.valueOf(dto.getMaterialUnit())));
            dto.setBomType("1");
            dto.setBomTypeDict("原料");
        }
        return list;
    }

    /**
     * 新增原料信息
     *
     * @param materialAwmateria 原料信息
     * @return 原料信息集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertAwmateria(MaterialAwmateriaVo materialAwmateria) throws Exception {
        materialAwmateria.setDeptId(SecurityUtils.getDeptId());
        materialAwmateria.setMaterialCode(sysMidSplitServiceImpl.splitStr(materialCodingMapper.selectCodingTypeThe(materialAwmateria.getMaterialType())));
        materialAwmateria.setCreateBy(SecurityUtils.getUsername());
        int ins = materialAwmateriaMapper.insertAwmateria(materialAwmateria);
        if (ins > 0) {
            if (materialAwmateria.getAlarmCode()!=null) {
                List<SysTheAlarm> list = alarmConfiguration(materialAwmateria.getAlarmCode());
                if (list.size() > 0) {
                    long op = materialAwmateria.getMaterialId();
                    String materialCode = materialAwmateria.getMaterialCode();
                    for (SysTheAlarm sysTheAlarm :
                            list) {

                        String roles = "";
                        for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {

                            roles = roles + sysTheAlarm.getRoleIds().get(i);
                            if (sysTheAlarm.getRoleIds().size()-1!=i){
                                roles = roles + ",";
                            }

                        }

                        sysTheAlarm.setAlarmRoleId(roles);
                        sysTheAlarm.setAlarmMaterialCode(materialCode);
                        sysTheAlarm.setAlarmAssociatedId(op);
                        sysTheAlarm.setAlarmOfMaterial(1);
                    }
                    if (list.size()!=0) {
                        ins = sysTheAlarmMapper.insertSysTheAlarm(list);
                    }
                    if (ins == 0) {
                        throw new SQLException("抛出异常");
                    }
                }
            }
            MaterialMqDto mq = new MaterialMqDto();
            mq.setMaterialCode(materialAwmateria.getMaterialCode());
            mq.setMaterialName(materialAwmateria.getMaterialName());
            mq.setMaterialSpec(materialAwmateria.getMaterialSpec());
            mq.setMaterialPlace(materialAwmateria.getMaterialPlace());
            mq.setMaterialCategory(1);
            mq.setMaterialType(materialAwmateria.getMaterialType());
            mq.setMaterialInspection(materialAwmateria.getMaterialInspection());
            mq.setMaterialUnit(String.valueOf(materialAwmateria.getMaterialUnit()));
            mq.setMaterialHair(materialAwmateria.getMaterialHair());
            mq.setMaterialClosed(materialAwmateria.getMaterialClosed());
            mq.setMaterialReminder(materialAwmateria.getMaterialReminder());//复检提醒
            mq.setMaterialQuality(materialAwmateria.getMaterialQuality());//保质期
            mq.setMaterialOverdue(materialAwmateria.getMaterialOverdue());//过期提醒
            mq.setMaterialMinSecurity(materialAwmateria.getMaterialMinSecurity());//最小安全库存

            MaterialMqUtil.materialMqSend(mq);
        }
        return ins;
    }

    /**
     * 封装告警配置json转集合
     *
     * @param json json数据
     * @return list
     */
    public List<SysTheAlarm> alarmConfiguration(JSONObject json) {
        List<SysTheAlarm> list = new ArrayList<SysTheAlarm>();
        List<SysTheAlarm> list2 = new ArrayList<SysTheAlarm>();
        List<SysTheAlarm> list3 = new ArrayList<SysTheAlarm>();
        JSONArray arr = json.getJSONArray("minSafety");
        JSONArray arr2 = json.getJSONArray("shelfLife");
        JSONArray arr3 = json.getJSONArray("theRe");
        list = JSONArray.parseArray(arr.toJSONString(), SysTheAlarm.class);
        list2 = JSONArray.parseArray(arr2.toJSONString(), SysTheAlarm.class);
        list3 = JSONArray.parseArray(arr3.toJSONString(), SysTheAlarm.class);
        list.addAll(list2);
        list.addAll(list3);
        return list;
    }


    /**
     * 删除原料信息
     *
     * @param materialId 原料信息ID
     * @return 原料信息集合
     */
    @Override
    public int deleteAwmateriaById(String materialId) throws Exception {
        String[] materialIdS = materialId.split(",");

        //同步删除原料信息
        MaterialMqDto mq = new MaterialMqDto();
        List<String> materialIdList = Arrays.asList(materialId.split(","));
        String awmateriaStr = materialAwmateriaMapper.getAwmateriaById(materialIdList);
        mq.setMaterialCode(awmateriaStr);
        //删除标识
        mq.setMark(3);
        MaterialMqUtil.materialMqSendDelete(mq);

        int is = materialAwmateriaMapper.deleteAwmateriaById(materialIdS);
        if (is > 0) {
            sysTheAlarmMapper.deleteSysTheAlarmById(materialIdS);
            if (is == 0) {
                throw new SQLException("抛出异常");
            }

        }
        return is;
    }

    /**
     * 查询单个原料信息
     *
     * @param materialId 原料信息ID
     * @return 原料信息集合
     */
    @Override
    public MaterialAwmateriaDto selectAwmateriaById(long materialId) {
        MaterialAwmateriaVo materialAwmateria = new MaterialAwmateriaVo();
        materialAwmateria.setMaterialId(materialId);
        List<MaterialAwmateriaDto> list = materialAwmateriaMapper.selectAwmateriaList(materialAwmateria);
        MaterialAwmateriaDto materialAwmateriaDto = list.get(0);
        int alarmOfMaterial = 1;
        List<SysTheAlarm> theList = sysTheAlarmMapper.selectSysTheAlarmList(materialId, alarmOfMaterial);
        MaterialAlarmVo materialAlarmVo = alarmConfigtType(theList);
        materialAwmateriaDto.setAlarmCode(materialAlarmVo);
        return materialAwmateriaDto;
    }

    /**
     * 封装返回告警配置
     *
     * @param List 集合
     * @return list
     */
    public MaterialAlarmVo alarmConfigtType(List<SysTheAlarm> List) {
        List<SysDictData> dictList = DictUtils.getDictCache("sys_alarm_mode");
        List<SysDictData> dictList2 = DictUtils.getDictCache("sys_alarm_unit");
        List<SysDictData> dictList3 = DictUtils.getDictCache("sys_alarm_nexus");
        MaterialAlarmVo materialAlarmVo = new MaterialAlarmVo();
        List<SysTheAlarm> list1 = new ArrayList<SysTheAlarm>();
        List<SysTheAlarm> list2 = new ArrayList<SysTheAlarm>();
        List<SysTheAlarm> list3 = new ArrayList<SysTheAlarm>();
        for (SysTheAlarm vo :
                List) {
            for (SysDictData sysData :
                    dictList) {
                if (String.valueOf(vo.getAlarmWay()).equals(sysData.getDictValue())) {
                    vo.setAlarmWayDict(sysData.getDictLabel());
                    break;
                }
            }
            for (SysDictData sysData2 :
                    dictList2) {
                if (String.valueOf(vo.getAlarmUnit()).equals(sysData2.getDictValue())) {
                    vo.setAlarmUnitDict(sysData2.getDictLabel());
                    break;
                }
            }
            for (SysDictData sysData3 :
                    dictList3) {
                if (String.valueOf(vo.getAlarmNexus()).equals(sysData3.getDictValue())) {
                    vo.setAlarmNexusDict(sysData3.getDictLabel());
                    break;
                }
            }
            if (vo.getAlarmRoleId()!=null&&!"".equals(vo.getAlarmRoleId())){
                List<String> list = Arrays.asList(vo.getAlarmRoleId().split(","));


                List<Long> str2 = new ArrayList<>();

                for (int i = 0; i < list.size(); i++) {
                    str2.add(Long.valueOf(list.get(i)));
                }


                vo.setRoleIds(str2);
            }


            int type = vo.getAlarmType();
            if (type == 1) {//最小安全库存告警
                list1.add(vo);
            } else if (type == 2) {//保质期告警
                list2.add(vo);
            } else {//复检日期告警
                list3.add(vo);
            }
        }
        materialAlarmVo.setMinSafety(list1);
        materialAlarmVo.setShelfLife(list2);
        materialAlarmVo.setTheRe(list3);
        return materialAlarmVo;
    }

    /**
     * 修改原料信息
     *
     * @param materialAwmateria 原料信息ID
     * @return 原料信息集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMaterialAwmateriaEdit(MaterialAwmateriaVo materialAwmateria) throws Exception {
        int ors = materialAwmateriaMapper.updateMaterialAwmateriaEdit(materialAwmateria);
        if (ors > 0) {
            MaterialMqDto mq = new MaterialMqDto();
            mq.setMaterialCode(materialAwmateria.getMaterialCode());
            mq.setMaterialName(materialAwmateria.getMaterialName());
            mq.setMaterialSpec(materialAwmateria.getMaterialSpec());
            mq.setMaterialCategory(1);
            mq.setMaterialType(materialAwmateria.getMaterialType());
            mq.setMaterialPlace(materialAwmateria.getMaterialPlace());
            mq.setMaterialInspection(materialAwmateria.getMaterialInspection());
            mq.setMaterialUnit(String.valueOf(materialAwmateria.getMaterialUnit()));
            mq.setMaterialHair(materialAwmateria.getMaterialHair());
            mq.setMaterialClosed(materialAwmateria.getMaterialClosed());
            mq.setMaterialReminder(materialAwmateria.getMaterialReminder());//复检提醒
            mq.setMaterialQuality(materialAwmateria.getMaterialQuality());//保质期
            mq.setMaterialOverdue(materialAwmateria.getMaterialOverdue());//过期提醒
            mq.setMaterialMinSecurity(materialAwmateria.getMaterialMinSecurity());//最小安全库存
            MaterialMqUtil.materialMqSend(mq);
            long materialId = materialAwmateria.getMaterialId();
            long sy = materialId;
            String materialCode = materialAwmateria.getMaterialCode();

             sysTheAlarmMapper.deleteSysTheAlarmOnById(materialId);
            if (ors > 0) {
                List<SysTheAlarm> list = alarmConfiguration(materialAwmateria.getAlarmCode());
                for (SysTheAlarm sysTheAlarm :
                        list) {


                    String roles = "";
                    for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {

                        roles = roles + sysTheAlarm.getRoleIds().get(i);

                        if (i != sysTheAlarm.getRoleIds().size() - 1) {
                            roles = roles + ",";
                        }
                    }

                    sysTheAlarm.setAlarmRoleId(roles);

                    sysTheAlarm.setAlarmAssociatedId(sy);
                    sysTheAlarm.setAlarmOfMaterial(1);
                    sysTheAlarm.setAlarmMaterialCode(materialCode);
                }
                if (list.size() != 0) {
                    ors = sysTheAlarmMapper.insertSysTheAlarm(list);
                }

                if (ors == 0) {
                    throw new SQLException("抛出异常");
                }

            } else {
                throw new SQLException("抛出异常");
            }

            //修改BOM主表和明细表中的物料名称和物料规格
            boolean updateBomInfo = materialBomHalfMapper.updateBomInfo(materialAwmateria.getMaterialName(),materialAwmateria.getMaterialCode());
            //修改Bom明细表中的物料名称，物料规格
            boolean updateBomDetail = materialBomHalfMapper.updateBomDetail(materialAwmateria.getMaterialName(),materialAwmateria.getMaterialCode());
        }
        return ors;
    }

    /**
     * 冻结/解冻
     *
     * @param materialAwmateria 原料信息
     * @return 原料信息集合
     */
    @Override
    public int updateAwmateriaEditFreeze(MaterialAwmateria materialAwmateria) {
        return materialAwmateriaMapper.updateAwmateriaEditFreeze(materialAwmateria);
    }


    /**
     * 树结构数据
     *
     * @param
     * @return 原料信息集合
     */
    @Override
    public List<ProjectRecursionDto> selectChildrenListThe() {
        return buildMenuTree(materialAwmateriaMapper.selectChildrenListThe());
    }

    /**
     * 树结构递归
     *
     * @param
     * @return
     */
    public static List<ProjectRecursionDto> buildMenuTree(List<ProjectRecursionDto> menus) {
        List<ProjectRecursionDto> returnList = new ArrayList<ProjectRecursionDto>();
        List<String> tempList = new ArrayList<String>();
        for (ProjectRecursionDto dept : menus) {
            tempList.add(dept.getId());
        }
        for (Iterator<ProjectRecursionDto> iterator = menus.iterator(); iterator.hasNext(); ) {
            ProjectRecursionDto menu = (ProjectRecursionDto) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(menus, menu);
                if (menu.getParentId() == 0) {
                    returnList.add(menu);
                }
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private static void recursionFn(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        // 得到子节点列表
        List<ProjectRecursionDto> childList = getChildList(list, t);
        t.setChildren(childList);
        for (ProjectRecursionDto tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 递归列表
     */
    private static List<ProjectRecursionDto> getChildList(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        List<ProjectRecursionDto> tlist = new ArrayList<ProjectRecursionDto>();
        Iterator<ProjectRecursionDto> it = list.iterator();
        while (it.hasNext()) {
            ProjectRecursionDto n = (ProjectRecursionDto) it.next();
            if (String.valueOf(n.getParentId().longValue()).equals(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private static boolean hasChild(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 根据物料编码查询详情
     *
     * @param materialCode
     * @return
     */
    @Override
    public MaterialAwmateriaDto selectAllByAlarmMaterialCode(String materialCode) {
        return materialAwmateriaMapper.selectAllByAlarmMaterialCode(materialCode);
    }

    /**
     *  根据物料编码获取详情（委外订单详情列表调用 fegin）
     * @param materialCode
     * @return
     */
    @Override
    public MaterialAwmateriaDto getAwmateriaViewByMaterialCode(String materialCode) {
        return materialAwmateriaMapper.getAwmateriaViewByMaterialCode(materialCode);
    }

    /**
     * 导入原料信息
     * @param coCustomer
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importMouldData(List<MaterialAwmateriaExport> coCustomer) {
        if (StringUtils.isNull(coCustomer) || coCustomer.size() == 0) {
            throw new GlobalException("导入原料信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        //原料单位
        List<SysDictData> levelArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (MaterialAwmateriaExport mouldModelExport : coCustomer) {
            MaterialAwmateriaVo materialAwmateriaVo = new MaterialAwmateriaVo();
            try {
                if (mouldModelExport.getMaterialName() == null || mouldModelExport.getMaterialType() == null || mouldModelExport.getMaterialUnit() == null) {
                    throw new GlobalException("存在必填字段为空,请核实");
                }

                materialAwmateriaVo.setMaterialName(mouldModelExport.getMaterialName());

                //通过原料类别名称查出原料类别id
                MaterialCoding materialCoding = materialCodingMapper.getMaterilTypeId(mouldModelExport.getMaterialType());

                if (materialCoding==null){
                    throw new GlobalException("不存在该原料类别导入失败");
                }
                materialAwmateriaVo.setMaterialSpec(mouldModelExport.getMaterialSpec());
                materialAwmateriaVo.setMaterialType((int) materialCoding.getCodingId());

                materialAwmateriaVo.setMaterialPlace(mouldModelExport.getMaterialPlace());
                materialAwmateriaVo.setSuppliersName(mouldModelExport.getMaterialSuppliers());
                if (mouldModelExport.getMaterialQuality()!=null) {
                    materialAwmateriaVo.setMaterialQuality(Integer.parseInt(mouldModelExport.getMaterialQuality()));
                }
                if (mouldModelExport.getMaterialOverdue()!=null){
                    materialAwmateriaVo.setMaterialOverdue(Integer.parseInt(mouldModelExport.getMaterialOverdue()));
                }
                if (mouldModelExport.getMaterialInspection()!=null){
                    materialAwmateriaVo.setMaterialInspection(Integer.parseInt(mouldModelExport.getMaterialInspection()));
                }
                if (mouldModelExport.getMaterialReminder()!=null){
                    materialAwmateriaVo.setMaterialReminder(Integer.parseInt(mouldModelExport.getMaterialReminder()));
                }
                if (mouldModelExport.getMaterialMinSecurity()!=null){
                    materialAwmateriaVo.setMaterialMinSecurity(Integer.parseInt(mouldModelExport.getMaterialMinSecurity()));
                }

                //原料单位
                for (Map.Entry<String, String> entry : levelMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getMaterialUnit())) {
                        materialAwmateriaVo.setMaterialUnit(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }

                //超收标志
                if ("开".equals(mouldModelExport.getMaterialClosed())){
                    materialAwmateriaVo.setMaterialClosed(1);
                }else{
                    materialAwmateriaVo.setMaterialClosed(2);
                }
                if ("开".equals(mouldModelExport.getMaterialHair())){
                    materialAwmateriaVo.setMaterialHair(1);
                }else{
                    materialAwmateriaVo.setMaterialHair(2);
                }

                //超发标志

                int i = insertAwmateria(materialAwmateriaVo);
                if (i==0){
                    throw new GlobalException("导入失败");
                }

                successNum++;
                successMsg.append(successNum).append("、原料信息 ").append(mouldModelExport.getMaterialName()).append(" 导入成功");

            } catch (Exception e) {
                failureNum++;
                String msg = failureNum + "、原料名称 " + mouldModelExport.getMaterialName() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new GlobalException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }

    /**
     * 获取告警信息
     * @param materialCode,type
     * @return
     */
    @Override
    public SysTheAlarm getAlarm(String materialCode,String type) {
        SysTheAlarm alarm = sysTheAlarmMapper.getAlarm(materialCode, type);

        if (alarm!=null){

            String alarmRoleId = alarm.getAlarmRoleId();
            String[] roles = alarmRoleId.split(",");



        //通过角色id查出用户列表
        List<Long> sysUserRole = sysUserRoleMapper.getUserList(roles);

        String role = "";

        for (int i = 0; i < sysUserRole.size(); i++) {

            role=role+sysUserRole.get(i);

            if (i!=sysUserRole.size()-1){
                role= role+",";
            }
        }
        //使用用户id覆盖角色id
        alarm.setAlarmRoleId(role);}

        return alarm;
    }

    /**
     * 树结构数据
     *
     * @param
     * @return 原料信息集合
     */
    @Override
    public List<ProjectRecursionDto> selectChildrenListThe2() {
        return materialAwmateriaMapper.selectChildrenListThe2();
    }
}
